/*******************************************************************************
 * Copyright (c) 2007 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.classdiagram.parsers.texteditor.vsldatatypes;

import java.util.Collection;
import java.util.Vector;


import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.DataType;
import org.eclipse.uml2.uml.OpaqueExpression;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Slot;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.classdiagram.parsers.modelgenerator.VSLGenerator;
import com.cea.papyrus.classdiagram.parsers.texteditor.LabelCompletionProcessor;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_BooleanValue_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_DefaultValue_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_EnumerationLiteral_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_Integer_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_NullValue_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_NumberLiteral_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_Real_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_StringLiteral_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_Tuple_CompletionProposal;
import com.cea.papyrus.classdiagram.parsers.texteditor.completionproposals.VSL_UnlimitedNatural_CompletionProposal;

/**
 * Completion processor for action language. <BR>
 * Main class to process the different completions given by the texteditor to
 * its user
 * 
 * @author Chokri MRAIDHA
 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor
 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor
 * @see com.cea.actionlanguage.sharedresources.texteditor.IPropertyLabelKeywords
 */
public class VSLLabelCompletionProcessor extends
LabelCompletionProcessor implements IContext {

	private Property property;
	private Slot slot;
	private DataType datatype;
	private DataType subdatatype;
	
	
	//private Map<String, Boolean> modifiersUsed; 

	public VSLLabelCompletionProcessor(DataType datatype) {
		this.datatype = datatype;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.classdiagram.parsers.texteditor.LabelCompletionProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
	 */
	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
			int documentOffset) {
		String text;
		String completeText;
		String prefix = "";
		String message = null;
		String[] textSplit;
		
		Collection<ICompletionProposal> result = null;
		int selectionRange = 0;
		int propertyPosition = 0;
		int context = 0;

		try {
			text = viewer.getDocument().get(0, documentOffset);
			completeText = viewer.getDocument().get();
			VSLGenerator generator = new VSLGenerator(datatype);
			selectionRange = viewer.getSelectedRange().y;
			
			if (!datatype.getAllAttributes().isEmpty()) {
				
				// tupleType
				message = generator.isTupleValid(completeText, datatype, documentOffset);
				
				
				subdatatype = generator.getSubDataType();
					
			}
	    	else {
	    		message = generator.parseAndValidateProperty (text, datatype);
	    		subdatatype = datatype;
	    	}

	    	context = generator.getContext();
			result = computeCompletions(viewer, context,
					documentOffset, selectionRange);
			if (message != null) {
				prefix = getPrefix(viewer, documentOffset);
				result = computeCompletions(viewer, context,
						documentOffset, selectionRange);				
			}
		} catch (BadLocationException e) {
			e.printStackTrace();
		}	
		return result.toArray(new ICompletionProposal[] {});
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.classdiagram.parsers.texteditor.LabelCompletionProcessor#computeCompletions(org.eclipse.jface.text.ITextViewer, int, int, int)
	 */
	public Collection<ICompletionProposal> computeCompletions(
			ITextViewer viewer, int context, int documentOffset,
			int selectionRange) {
		Vector<ICompletionProposal> v = new Vector<ICompletionProposal>();
		//PropertyModifierProposal modifierProposalComputer = new PropertyModifierProposal();;
		//modifierProposalComputer.setModifiersUsed(modifiersUsed);
		//System.err.println(modifierProposalComputer.getModifiersUsed());
		
		String prefix = getPrefix(viewer, documentOffset);
		switch (context) {
		
			// ENUMERATION
		case IContext.ENUMERATION:
			VSL_EnumerationLiteral_CompletionProposal enumerationCompletion = new VSL_EnumerationLiteral_CompletionProposal();
			enumerationCompletion.setDataType(subdatatype);
			
			v.addAll(enumerationCompletion.generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;
			
			// BOOLEAN: true, false
		case IContext.BOOLEAN_LITERAL:
			v.addAll(new VSL_BooleanValue_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;
			// STRING: 
		case IContext.STRING_LITERAL:
			v.addAll(new VSL_StringLiteral_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;
			// REAL: 
		case IContext.REAL_LITERAL:
			v.addAll(new VSL_Real_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;
			// INTEGER: 
		case IContext.INTEGER_LITERAL:
			v.addAll(new VSL_Integer_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;
			// UNLIMITED NATURAL: 
		case IContext.UNLIMITED_LITERAL:
			v.addAll(new VSL_UnlimitedNatural_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;
			
//			// DATETIME: date, time, day
//		case IContext.DATETIME_LITERAL:
//			v.addAll(new VSL_TimeStr_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_DateStr_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_DayStr_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
		
			// DATETIME SECOND: dateStr 
//		case IContext.SECOND:
//			v.addAll(new VSL_DateStr_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//		case IContext.CENTISEC:
//			v.addAll(new VSL_DateStr_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//		case IContext.DATE_STR:
//			v.addAll(new VSL_DayStr_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
			
			// NFP_VALUE_SPECIFICATION: expression, literal, interval, variable, tuple
		case IContext.NFP_VALUE_SPECIFICATION:
//			v.addAll(new VSL_Expression_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_NullValue_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_DefaultValue_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_BooleanValue_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_StringLiteral_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_Real_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_Integer_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_UnlimitedNatural_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_DateTime_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));			
			//v.addAll(new VSL_Interval_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_Variable_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;

		case IContext.TUPLE:
			VSL_Tuple_CompletionProposal tupleCompletion = new VSL_Tuple_CompletionProposal();
			
			tupleCompletion.setDataType(datatype);
			
			v.addAll(tupleCompletion.generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;

			
			// INTERVAL
//		case IContext.INTERVAL:
//			v.addAll(new VSL_Interval_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			//v.addAll(new NameCompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
			
		case IContext.INTERVAL_BOUND:
			v.addAll(new VSL_NumberLiteral_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_Tuple_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_Choice_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_Expression_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			break;
			
			// COLLECTION
//		case IContext.COLLECTION:
//			v.addAll(new VSL_Collection_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;

			
			// CHOICE
//		case IContext.CHOICE:
//			VSL_Choice_CompletionProposal choiceCompletion = new VSL_Choice_CompletionProposal();
//			
//			choiceCompletion.setDataType(datatype);
//			
//			v.addAll(choiceCompletion.generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
			
			
			// MIN: nullValue, defaultValue, booleanValue, dateTime, numberLiteral, STRING_LITERAL, variable, interval
//		case IContext.MIN:
//			v.addAll(new VSL_Variable_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_Integer_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_Real_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_StringLiteral_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_DateTime_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			//v.addAll(new VSL_Interval_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//			
//			// MAX: dateTime, numberLiteral, STRING_LITERAL, variable, interval
//		case IContext.MAX:
//			v.addAll(new VSL_Variable_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_Integer_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_Real_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_StringLiteral_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_DateTime_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//			
//		case IContext.EXPRESSION:
//			v.addAll(new VSL_Expression_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_TimeExpression_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//			
//		case IContext.TIME_EXPR:
//			v.addAll(new VSL_TimeExpression_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//			
//		case IContext.VARIABLE_NAME:
//			v.addAll(new VSL_VariableName_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//			
//		case IContext.TYPE_NAME:
//			v.addAll(new VSL_TypeName_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
//			
//		case IContext.INSTANT_OBS_NAME:
//			v.addAll(new VSL_ObsExpr_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			break;
						
		default:
//			v.addAll(new VSL_Expression_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_NullValue_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_DefaultValue_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_BooleanValue_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_StringLiteral_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_Real_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_Integer_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
			v.addAll(new VSL_UnlimitedNatural_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));
//			v.addAll(new VSL_DateTime_CompletionProposal().generateCompletionProposals(documentOffset, selectionRange, prefix));			
			break;

		}

		return v;
	}
	
}